package pres.lnk.utils;

import org.apache.commons.lang3.StringUtils;
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.ResourceBundleBasedAdapter;
import sun.util.resources.LocaleData;
import sun.util.resources.OpenListResourceBundle;

import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 获取JDK内置的一些资源数据
 *
 * @Author lnk
 * @Date 2018/7/20
 */
public class DataResourceUtil {
    private static List<Country> countries;
    private static List<Currency> currencies;
    private static List<Language> languages;

    /**
     * 获取所有国家和对应的二字编码和三字编码
     *
     * @return
     */
    public static List<Country> getCountries() {
        if (countries != null) {
            return countries;
        }

        OpenListResourceBundle resource = getLocaleData().getLocaleNames(Locale.CHINA);
        synchronized (resource) {
            if (countries != null) {
                return countries;
            }
            Set<String> data = resource.keySet();
            List<String> twoCodes = data.stream()
                    .filter(code -> !StringUtils.isNumeric(code))
                    .filter(code -> StringUtils.isAllUpperCase(code))
                    .collect(Collectors.toList());
            twoCodes.sort(Comparator.naturalOrder());
            countries = twoCodes.stream().map(code -> {
                Locale locale = new Locale("", code);
                String threeCode = null;
                try {
                    threeCode = locale.getISO3Country();
                } catch (Exception e) {
                }
                return new Country(resource.getString(code), code, threeCode);
            }).collect(Collectors.toList());
            return countries;
        }
    }

    /**
     * 获取所有币种和对应的简码
     *
     * @return
     */
    public static List<Currency> getCurrencies() {
        if (currencies != null) {
            return currencies;
        }

        OpenListResourceBundle resource = getLocaleData().getCurrencyNames(Locale.CHINA);
        synchronized (resource) {
            if (currencies != null) {
                return currencies;
            }
            Set<String> data = resource.keySet();
            List<String> codes = data.stream().filter(StringUtils::isAllLowerCase).collect(Collectors.toList());
            codes.sort(Comparator.naturalOrder());
            currencies = codes.stream().map(code -> new Currency(resource.getString(code), code.toUpperCase())).collect(Collectors.toList());
            return currencies;
        }
    }

    /**
     * 获取系统的语言
     *
     * @return
     */
    public static List<Language> getLanguages() {
        if (languages != null) {
            return languages;
        }

        OpenListResourceBundle resource = getLocaleData().getLocaleNames(Locale.CHINA);
        synchronized (resource) {
            if (languages != null) {
                return languages;
            }
            Set<String> data = resource.keySet();
            List<String> codes = data.stream()
                    .filter(code -> code.length() == 2 && StringUtils.isAllLowerCase(code))
                    .collect(Collectors.toList());
            codes.sort(Comparator.naturalOrder());
            languages = codes.stream().map(code -> new Language(resource.getString(code), code)).collect(Collectors.toList());
            return languages;
        }
    }

    public static void main(String[] args) {
//        List<Country> countries = getCountries();
//        countries.forEach(System.out::println);
//        List<Currency> currencies = getCurrencies();
//        currencies.forEach(System.out::println);
        List<Language> languages = getLanguages();
        languages.forEach(System.out::println);
    }

    private static LocaleData getLocaleData() {
        ResourceBundleBasedAdapter resource = ((ResourceBundleBasedAdapter) LocaleProviderAdapter.forJRE());
        return resource.getLocaleData();
    }


    public static class Country {
        // 国家名称
        private String name;
        // 二字编码
        private String twoCode;
        // 三字编码
        private String threeCode;

        private Country(String name, String twoCode, String threeCode) {
            this.name = name;
            this.twoCode = twoCode;
            this.threeCode = threeCode;
        }

        public String getName() {
            return name;
        }

        public String getTwoCode() {
            return twoCode;
        }

        public String getThreeCode() {
            return threeCode;
        }

        @Override
        public String toString() {
            return "Country{" +
                    "name='" + name + '\'' +
                    ", twoCode='" + twoCode + '\'' +
                    ", threeCode='" + threeCode + '\'' +
                    '}';
        }
    }

    public static class Currency {
        private String name;
        private String code;

        private Currency(String name, String code) {
            this.name = name;
            this.code = code;
        }

        public String getName() {
            return name;
        }

        public String getCode() {
            return code;
        }

        @Override
        public String toString() {
            return "Currency{" +
                    "name='" + name + '\'' +
                    ", code='" + code + '\'' +
                    '}';
        }
    }

    public static class Language {
        private String name;
        private String code;

        private Language(String name, String code) {
            this.name = name;
            this.code = code;
        }

        public String getName() {
            return name;
        }

        public String getCode() {
            return code;
        }

        @Override
        public String toString() {
            return "Language{" +
                    "name='" + name + '\'' +
                    ", code='" + code + '\'' +
                    '}';
        }
    }
}
